#include <grpcpp/ext/proto_server_reflection_plugin.h>
#include <grpcpp/grpcpp.h>
#include <grpcpp/health_check_service_interface.h>

#include <iostream>
#include <memory>
#include <string>

#include "calculator.grpc.pb.h"

using grpc::Server;
using grpc::ServerBuilder;
using grpc::ServerContext;
using grpc::Status;

class CalculatorServiceImpl final : public calculator::CalculatorService::Service {
public:
    Status Add(ServerContext* context, const calculator::AddRequest* request,
               calculator::AddResponse* response) override {
        int result = request->a() + request->b();
        response->set_result(result);
        std::cout << "Add: " << request->a() << " + " << request->b() << " = " << result << std::endl;
        return Status::OK;
    }

    Status Multiply(ServerContext* context, const calculator::MultiplyRequest* request,
                    calculator::MultiplyResponse* response) override {
        int result = request->a() * request->b();
        response->set_result(result);
        std::cout << "Multiply: " << request->a() << " * " << request->b() << " = " << result << std::endl;
        return Status::OK;
    }
};

void RunServer(const std::string& address) {
    CalculatorServiceImpl service;

    grpc::EnableDefaultHealthCheckService(true);
    grpc::reflection::InitProtoReflectionServerBuilderPlugin();

    ServerBuilder builder;
    builder.AddListeningPort(address, grpc::InsecureServerCredentials());
    builder.RegisterService(&service);

    std::unique_ptr<Server> server(builder.BuildAndStart());
    std::cout << "Server listening on " << address << std::endl;

    server->Wait();
}

int main(int argc, char** argv) {
    std::string address("0.0.0.0:50051");
    RunServer(address);
    return 0;
}
